﻿using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Photo.Application.System.Dict.Dto;
using Photo.Core.EnumSummary.System;
using Photo.Core.Utils;

namespace Photo.Application.System.Dict
{
    /// <summary>
    /// 系统数据字典
    /// </summary>
    [ApiDescriptionSettings(ApiGroupConsts.System, Module = ApiGroupConsts.System)]
    public class DictService : IDynamicApiController
    {
        private readonly IRepository<SysDictEntity> _sysDictRepository;

        public DictService(IRepository<SysDictEntity> sysDictRepository)
        {
            _sysDictRepository = sysDictRepository;
        }

        /// <summary>
        /// 获取字典类型列表
        /// </summary>
        /// <returns></returns>
        public List<KeyValueDto> GetDictTypeList()
        {
            var list = EnumUtil.EnumToList<EnumSysDictType>().Adapt<List<KeyValueDto>>();

            return list;
        }

        /// <summary>
        /// 添加数据字典
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Add(DictAddInput input)
        {
            await MutexUtil.MutexNoWait("/api/system/dict/add", async () =>
            {
                if (await _sysDictRepository.AnyAsync(o => o.Type == input.Type  && o.Value == input.Value))
                    throw Oops.Oh("数据字典值重复");

                var entity = input.Adapt<SysDictEntity>();

                await _sysDictRepository.InsertAsync(entity);
            });
        }

        /// <summary>
        /// 编辑数据字典
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Edit(DictEditInput input)
        {
            await MutexUtil.MutexNoWait("/api/system/dict/edit?" + input.Id, async () =>
            {
                var entity = await _sysDictRepository.GetAsync(input.Id, "当前数据字典不存在");

                if (await _sysDictRepository.AnyAsync(o => o.Id != input.Id && o.Type == entity.Type && o.Value == input.Value))
                    throw Oops.Oh("数据字典值重复");

                input.AdaptTo(ref entity);

                await _sysDictRepository.UpdateAsync(entity);
            });
        }

        /// <summary>
        /// 设置数据字典状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SetActive(PrimaryKey input)
        {
            await MutexUtil.MutexNoWait("/api/system/dict/setactive?" + input.Id, async () =>
            {
                var entity = await _sysDictRepository.GetAsync(input.Id, "当前数据字典不存在");

                entity.IsActive = !entity.IsActive;

                await _sysDictRepository.UpdateAsync(entity);
            });
        }

        /// <summary>
        /// 删除数据字典
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Del(PrimaryKey input)
        {
            await MutexUtil.MutexNoWait("/api/system/dict/del?" + input.Id, async () =>
            {
                var entity = await _sysDictRepository.GetAsync(input.Id, "当前数据字典不存在");

                await _sysDictRepository.DeleteAsync(entity);
            });
        }

        /// <summary>
        /// 获取数据字典列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<DictDto>> GetList(BaseInput<EnumSysDictType> input)
        {
            var list = await _sysDictRepository.GetListAsync<DictDto>(o => o.Type == input.Content, o => o.Sort);

            return list;
        }

        /// <summary>
        /// 获取数据字典详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<DictDto> GetInfo(PrimaryKey input)
        {
            var info = await _sysDictRepository.GetAsync<DictDto>(input.Id, "当前数据字典不存在");

            return info;
        }

        /// <summary>
        /// 获取数据字典树列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<XmSelectTreeDto>> GetTreeList(BaseInput<EnumSysDictType> input)
        {
            var list = await _sysDictRepository.Query()
                .Where(o => o.Type == input.Content)
                .OrderBy(o => o.Sort)
                .Select(o => new XmSelectTreeDto
                {
                    Value = o.Id,
                    Name = o.Value,
                    ParentValue = o.PId
                })
                .ToListAsync();

            return list.ToTree("Value", "ParentValue", "Children", "");
        }

    }
}
